using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Build.Utilities;
using Microsoft.Build.Framework;
using System.IO;
using System.Text.RegularExpressions;

namespace EnvironmentFile.Targets
{
	public class ReplaceTokensTask : Task
	{
		[Required]
		public String EnvironmentFile
		{
			get;
			set;
		}
		[Required]
		public String TokenPattern
		{
			get;
			set;
		}

		[Required]
		public String ConfigFile
		{
			get;
			set;
		}

		public override bool Execute()
		{
			String configText = null;
			try
			{
				configText = File.ReadAllText(ConfigFile);
			}
			catch(IOException ex)
			{
				Log.LogError("Error accessing " + ConfigFile + " : " + ex.Message);
				return false;
			}
			String environmentText = null;
			try
			{
				environmentText = File.ReadAllText(EnvironmentFile);
			}
			catch(IOException ex)
			{
				Log.LogError("Error accessing " + EnvironmentFile + " : " + ex.Message);
				return false;
			}
			Regex tokenPattern = null;
			try
			{
				tokenPattern = new Regex(TokenPattern);
			}
			catch(ArgumentException ex)
			{
				Log.LogError("Error parsing TokenPattern parameter : \"" + TokenPattern + "\" " + ex.Message);
				return false;
			}
			Dictionary<string, string> tokenValuePair = Parse(environmentText);
			foreach(Match token in tokenPattern.Matches(configText))
			{
				if(token.Groups.Count != 2) //The global match doesn't count
				{
					Log.LogError("TokenPattern \"" + TokenPattern + "\" must have one and only one group which reprensents the token name");
					return false;
				}
				string tokenStr = token.Groups[1].Value;
				string value;
				if(!tokenValuePair.TryGetValue(tokenStr, out value))
				{
					Log.LogError("Token '" + tokenStr + "' is found in the config file, but not present in the EnvironmentFile");
					return false;
				}
				configText = configText.Replace(token.Value, value);
			}
			try
			{
				File.WriteAllText(ConfigFile, configText);
			}
			catch(IOException ex)
			{
				Log.LogError("Error writing in " + ConfigFile + " : " + ex.Message);
				return false;
			}
			return true;
		}

		private Dictionary<string, string> Parse(string environmentText)
		{
			Dictionary<string, string> keyValues = new Dictionary<string, string>();
			foreach(Match match in new Regex("^([^=]+)=(.*)$", RegexOptions.Multiline).Matches(environmentText))
			{
				keyValues.Add(match.Groups[1].Value, match.Groups[2].Value.Replace("\r", ""));
			}
			return keyValues;
		}


	}
}
